<?php

namespace yphp;

/**
 * Class config
 * 实例类
 */
abstract class Instance
{
    // 实例列表
    private static $instances = ['yphp\\' => [], 'app\model\\' => [], 'app\controller\\' => []];
    // 对象类型
    private static $type = ['yphp\\' => [], 'app\model\\' => [], 'app\controller\\' => []];

    // 构造函数
    final  function __construct(){
    }

    // 创建实例
    final static function instance()
    {
        list($type, $name) = Yphp::searchClass(get_called_class());
        return self::createObject($type, $name, func_get_args());
    }

    // // 创建对象 错误用法 错误用法 错误用法
    // final protected static function createObject($type, $name, $args = [])
    // {
    //     $class = $type . $name;
    //     if (!empty(self::$type[$type][$name])) {
    //         if (self::$type[$type][$name] === self::single()) {
    //             $obj = self::$instances[$type][$name];
    //         } else {
    //             $argsKey = Safe::en64(serialize($args));
    //             if (key_exists($argsKey, self::$instances[$type][$name])) {
    //                 $obj = self::$instances[$type][$name][$argsKey];
    //             } else {
    //                 $obj = new $class();
    //                 method_exists($obj, 'construct') && call_user_func_array([$obj, 'construct'], $args);
    //                 self::$instances[$type][$name][$argsKey] = $obj;
    //             }
    //         }
    //     } else {
    //         $cache = null;
    //         $obj = new $class();
    //         method_exists($obj, 'construct') && $cache = call_user_func_array([$obj, 'construct'], $args);
    //         is_null($cache) && $cache = true;
    //         self::$type[$type][$name] = $cache;
    //         if ($cache === true) {
    //             self::$instances[$type][$name][Safe::en64(serialize($args))] = $obj;
    //         } else {
    //             self::$instances[$type][$name] = $obj;
    //         }
    //     }
    //     return $obj;
    // }

    // 创建对象，正确用法
    final static function createObject($type, $name, $args)
    {
        $class = $type . $name;
        if (empty(self::$type[$class])) {
            list($obj, $cache) = self::makeObj($class, $args);
            self::$type[$class] = $cache;
            if ($cache === true) {
                self::$instances[$type][$name][Safe::en64(serialize($args))] = $obj;
            } elseif ($cache === self::single()) {
                self::$instances[$type][$name] = $obj;
            }
        } else {
            if (self::$type[$class] === self::single()) {
                $obj = self::$instances[$type][$name];
            } else {
                $argsKey = Safe::en64(serialize($args));
                if (key_exists($argsKey, self::$instances[$type][$name])) {
                    $obj = self::$instances[$type][$name][$argsKey];
                } else {
                    $obj = self::makeObj($class, $args)[0];
                    self::$instances[$type][$name][$argsKey] = $obj;
                }
            }
        }
        return $obj;
    }


    final static function makeObj($class, $args)
    {
        $cache = null;
        $obj = new $class();
        method_exists($obj, 'construct') && $cache = call_user_func_array([$obj, 'construct'], $args);
        is_null($cache) && $cache = true;
        return [$obj, $cache];
    }



    // 单例调用(返回值不能为false、true)
    final protected static function single()
    {
        return 'single';
    }

    // 查询实例
    final static function searchInstance()
    {
        return self::$instances;
    }
}